package mt.dummy;

import java.util.ArrayList;

import mt.Order;
import mt.comm.ClientSideMessage;
import mt.comm.Message;
import mt.comm.ServerComm;
import mt.server.MicroTraderServer;

public class MicroTraderServerDummy implements MicroTraderServer {

	private ServerComm serverComm;
	private ArrayList<Order> orders;
	private ArrayList<ClientSideMessage> messages;
	private ArrayList<String> clients;

	/**
	 * Starts the server. Creates all the lists that are used.
	 * 
	 * @param serverComm
	 *            the object through which all communication with clients should
	 *            take place.
	 */

	@Override
	public void start(ServerComm serverComm) {
		this.serverComm = serverComm;
		orders = new ArrayList<Order>();
		messages = new ArrayList<ClientSideMessage>();
		clients = new ArrayList<String>();
		serverComm.start();

	}

	/**
	 * Adds a order to the orders list that is created in the start method.
	 * Informs all the clients that a new order was created.
	 * 
	 * @param order
	 *            the object that is added to the list.
	 */

	public void addOrder(Order order) {
		order.setServerOrderID(orders.size());
		orders.add(order);
		for (String string : clients)
			serverComm.sendOrder(string, order);
	}

	/**
	 * Goes through all the orders and compares each one with the sell order to see if this can be satisfied.
	 * 
	 * @param sell Object to be compared with all the objects on the orders list.
	 * 	
	 *            
	 */

	public void satisfactionOrder(Order sell) {
		for (Order buy : orders) {
			if (sell.getStock().equals(buy.getStock()) && sell.isSellOrder()
					&& buy.isBuyOrder()
					&& sell.getPricePerUnit() <= buy.getPricePerUnit()) {
				// como se actualiza tods os clients das orders ja removidas.
				if (sell.getNumberOfUnits() > buy.getNumberOfUnits()) {
					sell.setNumberOfUnits(sell.getNumberOfUnits()
							- buy.getNumberOfUnits());
					buy.setNumberOfUnits(0); // 0 so the client knows he needs
												// to erase it.
					messages.add(new Message(ClientSideMessage.Type.ORDER, buy));
					messages.add(new Message(ClientSideMessage.Type.ORDER, sell));
					orders.remove(buy);
					break;
				} else if (sell.getNumberOfUnits() < buy.getNumberOfUnits()) {
					buy.setNumberOfUnits(buy.getNumberOfUnits()
							- sell.getNumberOfUnits());
					sell.setNumberOfUnits(0);
					messages.add(new Message(ClientSideMessage.Type.ORDER, buy));
					messages.add(new Message(ClientSideMessage.Type.ORDER, sell));
					orders.remove(sell);
					break;
				} else {
					buy.setNumberOfUnits(0);
					sell.setNumberOfUnits(0);
					messages.add(new Message(ClientSideMessage.Type.ORDER, buy));
					messages.add(new Message(ClientSideMessage.Type.ORDER, sell));
					orders.remove(sell);
					orders.remove(buy);
					break;
				}
			}
		}
	}
	
	/**
	 * Connects a new client. Sends all orders to the client.
	 * 
	 * @param nickname String with the user nickname.
	 * 
	 */

	public void clientConnect(String nickname) {
		clients.add(nickname);
		for (Order order : orders) {
			serverComm.sendOrder(nickname, order);

		}
	}

	/**
	 * 
	 * Disconnects a client, removing all orders containing its nickname.
	 * 
	 * 
	 * @param nickname String with the user nickname.
	 */

	public void clientDisconnect(String nickname) {
		for (Order order : orders)
			if (order.getNickname().equals(nickname)) {
				order.setNumberOfUnits(0);
				messages.add(new Message(ClientSideMessage.Type.ORDER, order));
				orders.remove(order);

			}
		clients.remove(nickname);
		serverComm.disconnectClient(nickname);
	}

}
